feat: add the snapshot and dom tap commands for reading AUT DOM#34255
Closed
davidr-cy wants to merge 10 commits into
Closed
feat: add the snapshot and dom tap commands for reading AUT DOM#34255davidr-cy wants to merge 10 commits into
davidr-cy wants to merge 10 commits into
Conversation
cypress
|
|||||||||||||||||||||||||||||||||||||||||||
| Project |
cypress
|
| Branch Review |
davidr/feat/tap-cli/tap-snapshots
|
| Run status |
|
| Run duration | 11m 59s |
| Commit |
|
| Committer | David Rowe |
| View all properties for this run ↗︎ | |
| Test results | |
|---|---|
|
|
7
|
|
|
0
|
|
|
854
|
|
|
0
|
|
|
7726
|
| View all changes introduced in this branch ↗︎ | |
Warning
Partial Report: The results for the Application Quality reports may be incomplete.
UI Coverage
52.46%
|
|
|---|---|
|
|
29
|
|
|
32
|
Accessibility
98.9%
|
|
|---|---|
|
|
0 critical
3 serious
1 moderate
0 minor
|
|
|
18
|
Tests for review

commands/actions/type_special_chars.cy.ts • 0 failed tests • 5x-driver-electron
| Test | Artifacts | |
|---|---|---|
The first 5 failed specs are shown, see all 1024 specs in Cypress Cloud.
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-status
branch
from
July 10, 2026 01:20
78fb9cb to
8ed2606
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
from
July 10, 2026 01:20
ab6bd03 to
a4e16ac
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
from
July 10, 2026 15:05
a4e16ac to
ddcd8ac
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-status
branch
from
July 10, 2026 15:05
8ed2606 to
92dbaba
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
from
July 10, 2026 15:13
ddcd8ac to
a209a74
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-status
branch
from
July 10, 2026 15:13
92dbaba to
19f7898
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
from
July 10, 2026 19:12
a209a74 to
c196607
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-status
branch
from
July 10, 2026 19:12
19f7898 to
07941de
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
from
July 13, 2026 14:19
c196607 to
934ad77
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-status
branch
from
July 13, 2026 14:19
07941de to
7647a01
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-status
branch
from
July 13, 2026 15:11
7647a01 to
9bc0eb3
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
from
July 13, 2026 15:11
934ad77 to
52c822d
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-status
branch
from
July 13, 2026 16:48
9bc0eb3 to
1177708
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
from
July 13, 2026 16:48
52c822d to
7d67ba1
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
from
July 13, 2026 19:29
7d67ba1 to
d808bce
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-status
branch
from
July 13, 2026 19:29
1177708 to
f3c2f7c
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
from
July 14, 2026 19:20
d808bce to
f1fdd7e
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-status
branch
from
July 14, 2026 19:20
f3c2f7c to
89052b5
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
from
July 15, 2026 20:04
f1fdd7e to
1fd0a79
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-status
branch
from
July 15, 2026 20:04
89052b5 to
0128a8e
Compare
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1fd0a79. Configure here.
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-status
branch
from
July 15, 2026 20:22
0128a8e to
ff64dbc
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
from
July 15, 2026 20:22
1fd0a79 to
fe13d7e
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-status
branch
from
July 16, 2026 04:04
ff64dbc to
d51d9fb
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
2 times, most recently
from
July 16, 2026 13:30
11ea87a to
79a7e42
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-status
branch
from
July 16, 2026 13:30
d51d9fb to
4b3a0fd
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
from
July 16, 2026 16:39
79a7e42 to
7c7484c
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-status
branch
2 times, most recently
from
July 16, 2026 18:28
41633c7 to
9b9b0cc
Compare
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
from
July 16, 2026 18:28
7c7484c to
f307c6a
Compare
Two schema-driven subcommands let an agent inspect the app under test: - `snapshot <test> <command>` reads the DOM snapshot the driver captured for a command-log entry — the same snapshots the reporter shows on hover. It returns the page HTML (or, with --selector, just the matching elements), the element(s) the command acted on (the [data-cypress-el] subject), the before/after snapshot listing, and optionally the page stylesheets. Reads the live runner via getSnapshotPropsForLog rather than getTestsState, whose serialization blacklists snapshots. - `dom [selector]` reads the AUT's current live document for interactive inspection. Both cap returned HTML at a character budget (default 30000) and flag truncation, so an unscoped read of a heavy page can't flood the caller. Test and command ids are positional params on snapshot: commander 6 stores options as properties, so an option named `command` clashes with its built-in `command` property.
…mands Reads the app-under-test DOM directly over CDP instead of serializing it in the runner page: - Removes the app-side `snapshot` and `dom` tap commands (and their helpers/specs). Historical DOM will come from pinning a command (next), and live DOM now comes from CDP. - Extends `withTapSession` to expose the attached CDP client + session so extractors can run Page/DOM/CSS/Accessibility against the AUT frame. - Adds `resolveAutFrame`: the AUT is a same-process child frame of the runner page (name `Your project: '<name>'`) — verified empirically to be a child frame, not an OOPIF, so one attached session reaches it. - Adds the CLI-native `tap frame` command group and `frame dom`, which reads the current AUT DOM (whole page or a selector's matches) via an isolated world, capping output browser-side. `frame ax`, `frame inspect`, and the binding `pin` command follow. The frozen getSchema/exec contract is unchanged; `frame` is CLI-native.
`cypress tap frame ax [selector]` returns the app-under-test's accessibility tree — roles, names, values, and key states — from Accessibility.getFullAXTree scoped to the AUT frame, projected to a compact indented tree (noise roles collapsed, ignored nodes dropped) with a --max-nodes cap. A selector roots the read at a subtree by matching the element's backend node id; a non-matching selector is an empty result, a malformed one is INVALID_SELECTOR.
`cypress tap pin <test> <command> [--at]` renders a command's captured DOM snapshot into the live app-under-test frame (via the reporter's restore path), so the CDP `tap frame` commands can read that historical moment — its HTML, accessibility tree, computed styles — deterministically instead of whatever the live frame happens to show. `pin --clear` restores the pre-pin DOM; it is idempotent. The pin is app state that persists between tap calls (each CLI call is a fresh CDP connection, so no handle crosses them). Guards: NO_RUN, RUN_IN_PROGRESS, ALREADY_PINNED (one pin at a time), TEST_NOT_FOUND, COMMAND_NOT_FOUND, SNAPSHOT_UNAVAILABLE, SNAPSHOT_NOT_FOUND. The snapshot store's pinned flag is set so the reporter's hover machinery can't clobber the pinned DOM.
- `cypress tap frame inspect <selector>` returns one element's tag, attributes, curated computed styles, box rect, and accessibility node. It reads the element's info in an isolated world (getComputedStyle / getBoundingClientRect on the element) and takes only the AX node from CDP — avoiding the brittle requestNode/nodeId path. - `run-state` (and therefore `status`) now reports the currently pinned command, so a pin is always visible and a stranded one is recoverable.
Align with Playwright's naming for the accessibility tree (its ariaSnapshot / toMatchAriaSnapshot API and the "aria snapshot" its agent tooling returns). `tap frame ax` becomes `tap frame aria`; the extractor, its result types, and the per-element accessibility field on `frame inspect` follow suit. CDP protocol identifiers (AXNode, getFullAXTree) keep their names.
A pin leaked across spec switches and re-runs: the module-level pin state survived, so `status` kept reporting a pin that no longer existed and a `pin --clear` could restore a stale snapshot over the new run's DOM. Reconcile the pin against the current run before every pin/status/clear: the pin is live only while the exact snapshot object it rendered is still the command's current snapshot. A re-run re-captures fresh objects (even when the log id is reused) and a spec switch drops the command entirely — both fail the identity check, so the stale pin is released without restoring its now-gone DOM.
Route the pin through the app's native pin so the AUT shows the pinned banner/controls and the reporter command log reflects it — the pinned command highlights and its test opens (mirrors the existing unpin notification). Re-pinning the same command with a new --at now moves the pin to that snapshot in place instead of erroring ALREADY_PINNED; a different command still requires a clear first.
davidr-cy
force-pushed
the
davidr/feat/tap-cli/tap-snapshots
branch
from
July 16, 2026 18:43
f307c6a to
9bb4a60
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

cypress tapCLI (internal dev tooling); no separate public issue.Additional details
Adds two schema-driven
cypress tapsubcommands that let an agent read the app-under-test's DOM straight from the command log, so failures can be diagnosed from the terminal:tap snapshot <test> <command>— reads the DOM snapshot the driver captured for a command-log entry (the same snapshots the reporter shows on hover). Returns the page HTML, or with--selectorjust the matching elements; the element(s) the command acted on (the[data-cypress-el]subject); thebefore/aftersnapshot listing; and, with--styles, the page stylesheets.--atselects which snapshot;--max-charscaps the payload (default 30000, flagstruncated).tap dom [selector]— reads the AUT's current live document, for inspecting an interactive session.Implementation notes:
getSnapshotPropsForLog— the reporter's own hover seam — notgetTestsState, whose serialization blacklistssnapshots. The handler adopts the detached clone, readsouterHTML, and never mutates it, so it can't disturb the visible AUT.test/commandare positional params, not options: commander 6 stores options as properties, so an option namedcommandclashes with its built-incommandproperty.TapCommandError; a zero-count selector match is a result, not an error.knip.jsongets per-filetypesignores matching the existing tap convention.Steps to test
Manual end-to-end (open mode, Chrome-family or Electron browser):
node scripts/cypress.js open --project <project> --e2e --browser electroncypress tap run <spec>, then pollcypress tap statusuntil it finishes.cypress tap tests→ pick a failing test id;cypress tap commands --test <id>→ pick a command id.cypress tap snapshot <test> <command> --selector '<css>'to inspect the DOM at that command;cypress tap dom '<css>'to inspect the live page.Validated end-to-end against a real instance (Cypress 15.19.0): element-not-found, wrong-text assertion, and visibility-regression scenarios each diagnosed from the CLI, plus the full typed-error model.
How has the user experience changed?
No change to end-user-facing Cypress behavior — this is internal
cypress tapdeveloper tooling. Two new subcommands appear incypress taphelp when talking to a running instance.PR Tasks
cypress-documentation?type definitions?Note
Medium Risk
Pinning programmatically mutates the live AUT DOM and coordinates runner/reporter snapshot state; frame commands depend on CDP against the runner page, but scope is internal tap tooling rather than public Cypress APIs.
Overview
Adds CLI-native
dom,aria, andinspectsubcommands that short-circuit before the schema-driven tap program and read the app-under-test over Chrome DevTools Protocol (isolated world + Accessibility/DOM), including AUT frame resolution by the runner’sYour project:iframe name.Extends
TapSessionwithclient/sessionIdso those frame extractors share the same CDP attach/retry path as binding calls. Help text andbuild-programlist the frame commands for discovery; routing stays inrunFrame.Introduces the in-app
pintap command to render a command-log DOM snapshot into the live AUT (capture/restore via the AUT iframe, native runner pin UI, stale-pin reconciliation on re-run/spec switch).run-state/cypress tap statusnow includepinned, and the reporter syncs when pin is driven from tap (snapshotPinned/reporter:snapshot:pinned).Tests cover frame extractors, pin behavior, and updated CLI program registration; knip ignores new export-only types.
Reviewed by Cursor Bugbot for commit 9bb4a60. Bugbot is set up for automated code reviews on this repo. Configure here.